package com.spring.boot.quartz.controller;

import com.github.pagehelper.PageInfo;
import com.spring.boot.annotation.JobNameAnnotation;
import com.spring.boot.annotation.TriggerNameAnnotation;
import com.spring.boot.job.BaseJob;
import com.spring.boot.quartz.bean.JobAndTriggerBean;
import com.spring.boot.quartz.service.impl.IJobAndTriggerServiceImpl;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @program: springboot_vue
 * @description: 定时任务页面管理控制器
 * @author: ry
 * @create: 2018-08-16 14:39
 **/
@RestController
@RequestMapping(value = "/job")
@SuppressWarnings({"rawtypes", "unchecked"})
public class JobController {
    @Autowired
    private IJobAndTriggerServiceImpl iJobAndTriggerService;

    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;

    /**
     * 添加job
     *
     * @param jobClassName
     * @param jobGroupName
     * @param cronExpression
     * @throws Exception
     */
    @PostMapping(value = "addjob")
    public void addjob(@RequestParam(value = "jobClassName") String jobClassName,
                       @RequestParam(value = "jobGroupName") String jobGroupName,
                       @RequestParam(value = "cronExpression") String cronExpression) throws Exception {
                      addJob(jobClassName,jobGroupName,cronExpression);
    }
    public void addJob(String jobClassName, String jobGroupName, String cronExpression) throws Exception{
        // 通过SchedulerFactory获取一个调度器实例
        Scheduler scheduler=schedulerFactoryBean.getScheduler();
        //构建job信息
        JobDetail jobDetail= JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobname(jobClassName),jobGroupName).build();
        //表达式调度构建(任务执行的时间)
        CronScheduleBuilder scheduleBuilder=CronScheduleBuilder.cronSchedule(cronExpression);

        //按照新的cronExpression表达式构建一个新的trigger
        CronTrigger trigger=TriggerBuilder.newTrigger().withIdentity(triname(jobClassName),jobGroupName).withSchedule(scheduleBuilder).build();
        try {
            //创建调度器定时
            scheduler.scheduleJob(jobDetail,trigger);
        }catch (SchedulerException e){
            System.out.println("创建定时器失败"+e);
            throw new Exception("创建定时器失败"+e);
        }finally {
            //启动调度器
            scheduler.start();
        }
    }

    /**
     * 暂停job
     * @param jobClassName
     * @param jobGroupName
     * @throws Exception
     */
    @PostMapping(value = "pausejob'")
    public void pausejob(@RequestParam(value = "jobClassName") String jobClassName,
                         @RequestParam(value = "jobGroupName") String jobGroupName) throws Exception{
                jobPause(jobClassName,jobGroupName);
    }
    public void jobPause(String jobClassName, String jobGroupName) throws Exception {
              // 通过SchedulerFactory获取一个调度器实例
        Scheduler sched = schedulerFactoryBean.getScheduler();
        sched.pauseJob(JobKey.jobKey(jobClassName, jobGroupName));
    }

    /**
     * 恢复job
     * @param jobClassName
     * @param jobGroupName
     * @throws Exception
     */
    @PostMapping(value = "/resumejob")
    public void resumejob(@RequestParam(value = "jobClassName") String jobClassName,
                          @RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {
        jobresume(jobClassName, jobGroupName);
    }
    public void jobresume(String jobClassName, String jobGroupName) throws Exception {
        // 通过SchedulerFactory获取一个调度器实例
        Scheduler sched = schedulerFactoryBean.getScheduler();
        sched.resumeJob(JobKey.jobKey(jobClassName, jobGroupName));
    }

    /**
     * 更新job
     * @param jobClassName
     * @param jobGroupName
     * @param cronExpression
     * @throws Exception
     */
    @PostMapping(value = "/reschedulejob")
    public void rescheduleJob(@RequestParam(value = "jobClassName") String jobClassName,
                              @RequestParam(value = "jobGroupName") String jobGroupName,
                              @RequestParam(value = "cronExpression") String cronExpression) throws Exception {
        jobreschedule(jobClassName, jobGroupName, cronExpression);
    }
    public void jobreschedule(String jobClassName, String jobGroupName, String cronExpression) throws Exception {
        try {
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            TriggerKey triggerKey = new TriggerKey(triname(jobClassName), jobGroupName);
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);

            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            System.out.println("更新定时任务失败" + e);
            throw new Exception("更新定时任务失败");
        }
    }

    /**
     * 删除定时任务
     * @param jobClassName
     * @param jobGroupName
     * @throws Exception
     */
    @PostMapping(value = "/deletejob")
    public void deletejob(@RequestParam(value = "jobClassName") String jobClassName,
                          @RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {
        jobdelete(jobClassName, jobGroupName);
    }
    public void jobdelete(String jobClassName, String jobGroupName) throws Exception {
        // 通过SchedulerFactory获取一个调度器实例
        Scheduler sched = schedulerFactoryBean.getScheduler();
        sched.deleteJob(JobKey.jobKey(jobClassName, jobGroupName));
    }

    /**
     * 从数据库查询job
     * @param pageNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @GetMapping(value = "/queryjob")
    public Map<String, Object> queryjob(@RequestParam(value = "pageNum") Integer pageNum,
                                        @RequestParam(value = "pageSize") Integer pageSize) throws Exception {
        PageInfo<JobAndTriggerBean> jobAndTrigger = iJobAndTriggerService.getJobAndTriggerDetails("quartz",pageNum, pageSize);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("JobAndTrigger", jobAndTrigger);
        map.put("number", jobAndTrigger.getTotal());
        return map;
    }

    /**
     * 根据job任务名称注解获取job
     * @param jobClassName
     * @return
     * @throws Exception
     */
    public String jobname(String jobClassName) throws Exception {
        Class clazz = getClass(jobClassName).getClass();
        JobNameAnnotation jb = (JobNameAnnotation) clazz.getAnnotation(JobNameAnnotation.class);
        return jb.value();
    }

    /**
     * 触发器注解获取
     * @param jobClassName
     * @return
     * @throws Exception
     */
    public String triname(String jobClassName) throws Exception {
        Class clazz = getClass(jobClassName).getClass();
        // job任务名称注解获取
        TriggerNameAnnotation tr = (TriggerNameAnnotation) clazz.getAnnotation(TriggerNameAnnotation.class);
        return tr.value();
    }

    public static BaseJob getClass(String classname) throws Exception {
        Class class1 = Class.forName(classname);
        return (BaseJob) class1.newInstance();
    }
}